package com.srolorz.fmtp.thread.pool.executor.autoconfig;

import com.srolorz.fmtp.thread.pool.executor.ApplicationContext;
import com.srolorz.fmtp.thread.pool.executor.factory.ThreadPoolFactory;
import com.srolorz.fmtp.thread.pool.executor.pool.ThreadPoolManageEntity;
import com.srolorz.fmtp.thread.pool.executor.properties.BeanPropertiesBindRegistrar;
import com.srolorz.fmtp.thread.pool.executor.properties.ThreadPoolProperties;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author eleven
 */

@Configuration
@AutoConfiguration
@Import({BeanPropertiesBindRegistrar.class})
public class ThreadPoolAutoConfigure {
    private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPoolAutoConfigure.class);

    public ThreadPoolAutoConfigure() {
        this.initThreadPoolService();
    }

    private void initThreadPoolService() {
        LOGGER.info("=============start init thread pool=============");
        List<ThreadPoolProperties> list = (List) ApplicationContext.build().get("threadPoolProperties");
        AtomicInteger i = new AtomicInteger();
        list.forEach(properties -> {
            TimeUnit timeUnit = null;
            if (StringUtils.isBlank(properties.getUnit())) {
                LOGGER.warn("thread Unit param is null, use the default param-SECONDS.");
                timeUnit = TimeUnit.SECONDS;
            } else {
                TimeUnit.valueOf(TimeUnit.class, properties.getUnit());
            }
            String threadGroupName = Optional.ofNullable(properties.getThreadGroupName()).orElse("fmtp-thread-pool-" + i.getAndIncrement());
            String threadNamePrefix = Optional.ofNullable(properties.getThreadNamePrefix()).orElse("srolorz-");
            ThreadPoolManageEntity entity = new ThreadPoolManageEntity(threadNamePrefix, properties.getCorePoolSize(),
                    properties.getMaximumPoolSize(), properties.getKeepAliveTime(), timeUnit, properties.getWorkerQueueSize());
            entity.setThreadGroupName(threadGroupName);
            ThreadPoolFactory.addThreadPool(entity);
            LOGGER.info("=============thread pool info[{}]=============", threadGroupName);
            LOGGER.info("CorePoolSize={}", entity.getCorePoolSize());
            LOGGER.info("MaximumPoolSize={}", entity.getMaxPoolSize());
            LOGGER.info("KeepAliveTime={}", entity.getKeepAliveTime());
            LOGGER.info("TimeUnit={}", entity.getTimeUnit());
            LOGGER.info("WorkQueueSize={}", entity.getWorkQueueSize());
            LOGGER.info("=============================================");
        });
        LOGGER.info("=============init thread pool success=============");
    }
}
